#include "include/rpc_server.h"
#include "include/rpc_helper.h"
#include "include/event_manager.h"

#include "rpc/socket.h"
#include "rpc/rpc_env.h"
#include "rpc/acceptor.h"
#include "rpc/connection.h"
#include "rpc/socket_opt.h"
#include "rpc/rpc_protocol.h"
#include "rpc/event_pooler.h"

namespace rpc {

RpcServer::RpcServer(EventManager* base_poller, const std::string& ip,
                     uint16 port)
    : base_poller_(base_poller), ip_(ip), port_(port) {
  CHECK_NOTNULL(base_poller_);
}

RpcServer::~RpcServer() {
  ScopedMutex l(&conn_mutex_);
  STLMapUnRef(&conn_map_);
}

bool RpcServer::Start() {
  CHECK_NOTNULL(ev_handle_.get());
  RpcEnv env;
  event_pooler_.reset(new EventManagerPool(base_poller_));
  if (event_pooler_.get() == NULL || !event_pooler_->Start()) {
    return false;
  }

  acceptor_.reset(new Acceptor(this, base_poller_));
  CHECK_NOTNULL(acceptor_.get());
  acceptor_->SetEventHandle(ev_handle_.get());
  CHECK(acceptor_->Init(ip_, port_));

  return true;
}

void RpcServer::RemoveTransaction(Connection* trans) {
  CHECK(trans != NULL);
  scoped_ref<Connection> tmp(trans);
  const Socket* s = trans->getSocket();
  ScopedMutex l(&conn_mutex_);
  conn_map_.erase(s->Fd());
}

void RpcServer::AddTransaction(Connection* trans) {
  CHECK(trans != NULL);
  trans->Ref();

  const Socket* s = trans->getSocket();
  ScopedMutex l(&conn_mutex_);
  conn_map_[s->Fd()] = trans;
}

EventManager* RpcServer::getPoller() {
  return event_pooler_->getPoller();
}

}
